﻿using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Web;
using System.Linq;
using System.Text;
using EventbriteService.Util;

namespace EventbriteService
{
    public class UrlRequestBuilder : IUrlBuilder
    {
        const string DefaultBaseUrl = "https://www.eventbriteapi.com/";

        private IDictionary<string, string> _parameters;
        private IEventBriteConfiguration _configuration;
        private string _queryString;
        private string _requestMethod;
        private string _requestBase;
        private string _format;
        private bool _displayRepeat;
        private bool _expand;

        public UrlRequestBuilder(IDictionary<string, string> parameters)
        {
            _parameters = parameters;
            _format = MessageFormat.JSON;
        }

        public UrlRequestBuilder() : this(new Dictionary<string, string>()) { }

        public IUrlBuilder AddQueryString(string query)
        {
            if (String.IsNullOrEmpty(query))
                query = BuildQueryString();
            _queryString = query;

            return this;

        }

        public IUrlBuilder AddRequestMethod(string request)
        {
            _requestMethod = request;

            return this;
        }

        public IUrlBuilder AddRequestBaseUrl(string baseUrl = "")
        {
            if (String.IsNullOrEmpty(baseUrl))
                baseUrl = DefaultBaseUrl;

            _requestBase = baseUrl;

            return this;
        }

        public IUrlBuilder AddFormat(string format)
        {
            if (String.IsNullOrEmpty(format))
                format = MessageFormat.JSON;
            _format = format;
           
            return this;
        }

        public IUrlBuilder AddConfiguration(IEventBriteConfiguration config)
        {
            _configuration = config;

            return this;
        }

        public IUrlBuilder AddQueryString(Action<IParametersAdapter> parameters)
        {
            parameters.Invoke(this);

            return this;
        }

        public IUrlBuilder AddRepeatSchedule()
        {
            _displayRepeat = true;

            return this;
        }
       
        public string this[string key]
        {
            get
            {
                if (_parameters.ContainsKey(key))
                    return _parameters[key];
                return string.Empty;
            }
            set
            {
                if (_parameters.ContainsKey(key))
                {
                    _parameters[key] = value;
                }
                else
                {
                    _parameters.Add(key, value);
                }
            }
        }

        public void ClearParameters()
        {
            _parameters.Clear();
        }

        public Uri Build()
        {
            if (_configuration == null || String.IsNullOrEmpty(_configuration.AppKey))
                throw new ArgumentException("You need to configure Application Key");

            if (String.IsNullOrEmpty(_queryString))
            {
                _queryString = BuildQueryString();
            }

            return DoBuild();
        }

        private Uri DoBuild()
        {
            UriBuilder uri = new UriBuilder(_requestBase);
            uri.Path = string.Format("/v3/{0}/", _requestMethod);

            if (!String.IsNullOrEmpty(_queryString))
                uri.Query = string.Format("{0}{1}{2}", uri.Query.TrimStart('?'), _queryString, "&");

            if(_expand)
                uri.Query = string.Format("{0}expand=organizer,venue,category,format,ticket_classes&token={1}", uri.Query.TrimStart('?'), _configuration.AppKey);
            else
                uri.Query = string.Format("{0}token={1}", uri.Query.TrimStart('?'), _configuration.AppKey);

            _configuration.RequestURL = uri.Uri.ToString();
            return uri.Uri;
        }

        private string BuildQueryString()
        {
            NameValueCollection queryString = HttpUtility.ParseQueryString("");

            foreach (var item in _parameters)
            {
                if (!String.IsNullOrEmpty(item.Value))
                {
                    queryString.Add(item.Key, item.Value);
                }
            }
            return queryString.ToString();
        }

        public IUrlBuilder Expand()
        {
            _expand = true;
            
            return this;
        }
    }
}
